]> dgit.raspbian.org Git - libreoffice.git/commitdiff
[PATCH] Reapply "firebird: keep each embedded database's files in one directory"
authorXisco Fauli <xiscofauli@libreoffice.org>
Fri, 17 Jul 2026 09:59:00 +0000 (11:59 +0200)
committerRene Engelhard <rene@debian.org>
Sat, 3 Oct 2026 10:46:08 +0000 (12:46 +0200)
This reverts commit 23a5d0dc305fc04bdd277b24db8d5c8e41aa9ccd.

it also contains https://gerrit.collaboraoffice.com/c/core/+/7093
"firebird: upper-case the DatabaseAccess Restrict path on Windows"

Change-Id: I52ea962a51da19a112892d6a2497a7ddf682c579
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208212
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
(cherry picked from commit e4dc6a3cb2bfbf9d4c1e30e777b0f46417cf4c92)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208224
Reviewed-by: Ilmari Lauhakangas <ilmari.lauhakangas@libreoffice.org>
Tested-by: Ilmari Lauhakangas <ilmari.lauhakangas@libreoffice.org>
Reviewed-by: Hossein <hossein@libreoffice.org>
Gbp-Pq: Name CVE-2026-63266-2.diff

connectivity/source/drivers/firebird/Connection.cxx
connectivity/source/drivers/firebird/Connection.hxx
connectivity/source/drivers/firebird/Driver.cxx
connectivity/source/drivers/firebird/Driver.hxx

index ddeaa249e54fa3c8c87284bc0feb020a39a4c619..9ab978726d9f0d0e63abd709a26da3950188796f 100644 (file)
@@ -121,7 +121,8 @@ struct ConnectionGuard
 
 }
 
-void Connection::construct(const OUString& url, const Sequence< PropertyValue >& info)
+void Connection::construct(const OUString& url, const Sequence< PropertyValue >& info,
+                           const OUString& rDatabaseDataDirectoryURL)
 {
     ConnectionGuard aGuard(m_refCount);
 
@@ -161,7 +162,7 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >&
 
             bIsNewDatabase = !m_xEmbeddedStorage->hasElements();
 
-            m_pDatabaseFileDir.reset(new ::utl::TempFileNamed(nullptr, true));
+            m_pDatabaseFileDir.reset(new ::utl::TempFileNamed(&rDatabaseDataDirectoryURL, true));
             m_pDatabaseFileDir->EnableKillingFile();
             m_sFirebirdURL = m_pDatabaseFileDir->GetFileName() + "/firebird.fdb";
             m_sFBKPath = m_pDatabaseFileDir->GetFileName() + "/firebird.fbk";
index 16ac0ffa278d0e9ed25a6b8c15827fe349b7fb1c..fb142283c72b6391a79cb60198b405afd09ce7c2 100644 (file)
@@ -163,7 +163,8 @@ namespace connectivity::firebird
             /// @throws css::sdbc::SQLException
             /// @throws css::uno::RuntimeException
             void construct( const OUString& url,
-                                    const css::uno::Sequence< css::beans::PropertyValue >& info);
+                                    const css::uno::Sequence< css::beans::PropertyValue >& info,
+                                    const OUString& rDatabaseDataDirectoryURL);
 
             const OUString& getConnectionURL()  const   {return m_sConnectionURL;}
             bool            isEmbedded()        const   {return m_bIsEmbedded;}
index 167072ca71c866ec64fbb12dc2ce560a175c20b6..1f345d772ac6b0c80f6f8d62817345af6051cb5c 100644 (file)
@@ -48,6 +48,7 @@ namespace {
 constexpr OUString our_sFirebirdTmpVar = u"FIREBIRD_TMP"_ustr;
 constexpr OUString our_sFirebirdLockVar = u"FIREBIRD_LOCK"_ustr;
 constexpr OUString our_sFirebirdMsgVar = u"FIREBIRD_MSG"_ustr;
+constexpr OUString our_sFirebirdRootVar = u"FIREBIRD"_ustr;
 #ifdef MACOSX
 constexpr OUString our_sFirebirdLibVar = u"LIBREOFFICE_FIREBIRD_LIB"_ustr;
 #endif
@@ -58,12 +59,15 @@ FirebirdDriver::FirebirdDriver(const css::uno::Reference< css::uno::XComponentCo
     , m_aContext(_rxContext)
     , m_firebirdTMPDirectory(nullptr, true)
     , m_firebirdLockDirectory(nullptr, true)
+    , m_firebirdDataDirectory(nullptr, true)
+    , m_bConfined(false)
 {
     // ::utl::TempFile uses a unique temporary directory (subdirectory of
     // /tmp or other user specific tmp directory) per instance in which
     // we can create directories for firebird at will.
     m_firebirdTMPDirectory.EnableKillingFile(true);
     m_firebirdLockDirectory.EnableKillingFile(true);
+    m_firebirdDataDirectory.EnableKillingFile(true);
 
     // Overrides firebird's default of /tmp or c:\temp
     osl_setEnvironment(our_sFirebirdTmpVar.pData, m_firebirdTMPDirectory.GetFileName().pData);
@@ -71,6 +75,41 @@ FirebirdDriver::FirebirdDriver(const css::uno::Reference< css::uno::XComponentCo
     // Overrides firebird's default of /tmp/firebird or c:\temp\firebird
     osl_setEnvironment(our_sFirebirdLockVar.pData, m_firebirdLockDirectory.GetFileName().pData);
 
+    // Keep the files firebird opens or creates together in one directory.
+    // Embedded databases are extracted here, and DatabaseAccess = Restrict
+    // keeps any associated files firebird makes for it under the same
+    // directory. firebird reads this firebird.conf from the directory the
+    // FIREBIRD variable names, once, on its first use, so it has to be set
+    // before the first connection.
+    OUString sDataDirPath;
+    ::osl::FileBase::getSystemPathFromFileURL(m_firebirdDataDirectory.GetURL(), sDataDirPath);
+
+#if defined(_WIN32)
+    // firebird upper-cases the database path before the exact-match
+    // DatabaseAccess check, so match that here.
+    sDataDirPath = sDataDirPath.toAsciiUpperCase();
+#endif
+
+    OString sConf = "DatabaseAccess = Restrict "
+        + OUStringToOString(sDataDirPath, RTL_TEXTENCODING_UTF8) + "\n";
+
+    OUString sConfURL = m_firebirdDataDirectory.GetURL() + "/firebird.conf";
+    ::osl::File aConfFile(sConfURL);
+    if (aConfFile.open(osl_File_OpenFlag_Create | osl_File_OpenFlag_Write) == ::osl::FileBase::E_None)
+    {
+        sal_uInt64 nWritten = 0;
+        if (aConfFile.write(sConf.getStr(), sConf.getLength(), nWritten) == ::osl::FileBase::E_None
+            && nWritten == static_cast<sal_uInt64>(sConf.getLength()))
+        {
+            osl_setEnvironment(our_sFirebirdRootVar.pData, sDataDirPath.pData);
+            m_bConfined = true;
+        }
+        aConfFile.close();
+    }
+
+    SAL_WARN_IF(!m_bConfined, "connectivity.firebird",
+                "could not write " << sConfURL << ", firebird connections will be refused");
+
 #ifndef SYSTEM_FIREBIRD
     // Overrides firebird's hardcoded default of /usr/local/firebird on *nix,
     // however on Windows it seems to use the current directory as a default.
@@ -107,6 +146,7 @@ void FirebirdDriver::disposing()
 
     osl_clearEnvironment(our_sFirebirdTmpVar.pData);
     osl_clearEnvironment(our_sFirebirdLockVar.pData);
+    osl_clearEnvironment(our_sFirebirdRootVar.pData);
 
 #ifndef SYSTEM_FIREBIRD
     osl_clearEnvironment(our_sFirebirdMsgVar.pData);
@@ -148,8 +188,18 @@ Reference< XConnection > SAL_CALL FirebirdDriver::connect(
     if ( ! acceptsURL(url) )
         return nullptr;
 
+    // Without the firebird.conf that keeps firebird inside its own directory
+    // we do not open any database.
+    if (!m_bConfined)
+    {
+        ::connectivity::SharedResources aResources;
+        const OUString sMessage = aResources.getResourceString(STR_COULD_NOT_LOAD_FILE).replaceFirst(
+            "$filename$", u"firebird.conf");
+        ::dbtools::throwGenericSQLException(sMessage, *this);
+    }
+
     rtl::Reference<Connection> pCon = new Connection();
-    pCon->construct(url, info);
+    pCon->construct(url, info, getDatabaseDataDirectoryURL());
 
     m_xConnections.emplace_back(*pCon);
 
index d884b5008d6a95adc8ceb6970c33a3ea761817c2..0f5172f6222cb2aafd24fb9e0f067cd6c65d9fcb 100644 (file)
@@ -47,6 +47,8 @@ namespace connectivity::firebird
             css::uno::Reference<css::uno::XComponentContext> m_aContext;
             ::utl::TempFileNamed m_firebirdTMPDirectory;
             ::utl::TempFileNamed m_firebirdLockDirectory;
+            ::utl::TempFileNamed m_firebirdDataDirectory;
+            bool m_bConfined;
 
         protected:
             ::osl::Mutex                m_aMutex;       // mutex is need to control member access
@@ -60,6 +62,11 @@ namespace connectivity::firebird
             virtual ~FirebirdDriver() override;
             const css::uno::Reference<css::uno::XComponentContext>& getContext() const { return m_aContext; }
 
+            // The directory that embedded databases are extracted into. Each
+            // connection makes its own subdirectory here, and firebird keeps
+            // associated files it creates for them under this directory as well.
+            OUString getDatabaseDataDirectoryURL() const { return m_firebirdDataDirectory.GetURL(); }
+
             // OComponentHelper
             virtual void SAL_CALL disposing() override;